/*
 * condition_variable.h
 *
 *  Created on: May 30, 2013
 *      Author: David
 */

#include <stdio.h>
#include <pthread.h>
#include "condition_variable.h"



char* condition_init( ConditionVariable *this ) {
  //this->atomic = PTHREAD_MUTEX_INITIALIZER;
  this->pid_queue = newQueueConstructor();
  this->mutex_queue = newQueueConstructor();

  this->wait = condition_wait;
  this->notify = condition_notify;
}

char* condition_wait( ConditionVariable *this , Mutex *mutex , PCBPtr process ) {
  pthread_mutex_lock(&(this->atomic));

  this->pid_queue->enqueue(this->pid_queue, (int)process);
  this->mutex_queue->enqueue(this->mutex_queue, (int)mutex);
  mutex->unlock(mutex,process);

  pthread_mutex_unlock(&(this->atomic));
  return 0;
}

char* condition_notify( ConditionVariable *this , PCBPtr process , PCBPtr *popped_process, Mutex *popped_mutex) {
  pthread_mutex_lock(&(this->atomic));

  PCBPtr process2 =  (PCBPtr) this->pid_queue->dequeue(this->pid_queue);
  Mutex *mutex = (Mutex*)this->mutex_queue->dequeue(this->mutex_queue);
  mutex->lock(mutex,process2);

  popped_process = &process2;
  (*popped_mutex) = *mutex;
  
  pthread_mutex_unlock(&(this->atomic));
  return 0;
}


/*
int main(void) {
  Mutex mutex;
  ConditionVariable cond_var;
  mutex_init(&mutex);
  condition_init(&cond_var);
  char* error;


  error = mutex.lock(&mutex,1); if(error) printw("%s\n",error);
  printw("lock   1 -> owner %d\n", mutex.locked);
  mutex.queue->display(mutex.queue);
  printw("-----------------\n");

  error = cond_var.wait(&cond_var,&mutex,1); if(error) printw("%s\n",error);
  printw("wait   1 -> owner %d\n", mutex.locked);
  mutex.queue->display(mutex.queue);
  printw("-----------------\n");

  error = mutex.lock(&mutex,2); if(error) printw("%s\n",error);
  printw("lock   2 -> owner %d\n", mutex.locked);
  mutex.queue->display(mutex.queue);
  printw("-----------------\n");

  error = cond_var.notify(&cond_var,2); if(error) printw("%s\n",error);
  printw("notify 2 -> owner %d\n", mutex.locked);
  mutex.queue->display(mutex.queue);
  printw("-----------------\n");



  error = mutex.unlock(&mutex,2); if(error) printw("%s\n",error);
  printw("ulock  2 -> owner %d\n", mutex.locked);
  mutex.queue->display(mutex.queue);
}
*/
